
#include <string.h>
#include <cstring>
#include <unistd.h>
#include <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <strings.h>
#include <stdlib.h>
#include <string>
#include <time.h>
#include <vector>
#include <pthread.h>
#include "tlv.h"
#include "client.h"

using namespace std;

void clientTCP::processThreadProcess()
{
	char test[80001];

	ReceiveBlock blockParser;

	while(m_active)
	{
		int data_len = read(m_listenFd, test, 80000);
//		std::cout << "len=" << data_len << " ";

		if(data_len == 0)
			break;

		if(blockParser.parseData(test,data_len))
		{
			continue;
		}

		do {
			com::Block block;
			block.ParseFromString(blockParser.getBlock());
			receiveBlock(block);
		} while(blockParser.nextBlock());

	}
	std::cout << "client dead" << std::endl;
	m_active = false;
	close(m_listenFd);

}
clientTCP::clientTCP(std::string const& host, int port): ThreadService(false /* do not start process*/), m_active(false)
{
	pthread_mutex_init(&m_send_block_mutex, NULL);
	std::cout << "host=" << host << " port=" << port << std::endl;
	int portNo;
	struct sockaddr_in svrAdd;
	struct hostent *server;


	portNo = port;


	//create client skt
	m_listenFd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

	if(m_listenFd < 0)
	{
		cerr << "Cannot open socket" << endl;
	}

	server = gethostbyname(host.c_str());

	if(server == NULL)
	{
		cerr << "Host does not exist" << endl;
	}

	bzero((char *) &svrAdd, sizeof(svrAdd));
	svrAdd.sin_family = AF_INET;

	bcopy((char *) server -> h_addr, (char *) &svrAdd.sin_addr.s_addr, server -> h_length);

	svrAdd.sin_port = htons(portNo);

	int checker = connect(m_listenFd,(struct sockaddr *) &svrAdd, sizeof(svrAdd));

	if (checker < 0)
	{
		cerr << "Cannot connect!" << endl;
	}
	m_active = true;
	startProcess();

}
bool clientTCP::sendString(com::Block const& block)
{
	if(m_active)
	{
		std::string blockString;
		block.SerializeToString(&blockString);
//			std::cout << "send" << std::endl;
		std::string data = sendBlock(blockString);
//		write(m_listenFd, data.c_str(), data.size());
		std::cout << "Send" << std::endl;
		pthread_mutex_lock(&m_send_block_mutex);
		std::cout << "SendOK" << std::endl;
		send(m_listenFd, data.c_str(), data.size(), MSG_DONTWAIT);
		pthread_mutex_unlock(&m_send_block_mutex);
		return true;
	}
	return false;
}
/*
	void clientTCP::receiveBlock(com::Block const& block)
	{
//		std::cout << "receiveBlock=" << data << std::endl;
	}*/
